#!/bin/sh

# 支持的 yocto 版本
YOCTOVERSION="kirkstone"

PROG_NAME="setup.sh"

DEFAULT_DISTRO="alpha-distro"

# 目录设置
ROOT_DIR=$(dirname $(readlink -f "\$0"))
SOURCES_DIR=${ROOT_DIR}/sources
OE_ROOT_DIR=${SOURCES_DIR}/poky
if [ -e ${ROOT_DIR}/${SOURCES_DIR}/oe-core ]; then
    OE_ROOT_DIR=${SOURCES_DIR}/oe-core
fi

# 检查当前用户是否是 root 用户
if [ "$(whoami)" = "root" ]; then
    echo "ERROR: Do not use the BSP as root. Exiting..."
    unset ROOT_DIR PROG_NAME DISTRO DEFAULT_DISTRO
    return
fi

clean_up()
{
   unset PROG_NAME ROOT_DIR SOURCES_DIR OE_ROOT_DIR PROJECT_DIR MACHINE \
         CPUS JOBS THREADS DOWNLOADS CACHES DISTRO DEFAULT_DISTRO

   unset -f usage prompt_message
}

usage() {
    echo "Usage: . $PROG_NAME -m <machine>"

    echo "    Optional parameters:
    * [-m machine]: the target machine to be built.
    * [-e layers]:  extra layer names
    * [-D distro]:  override the default distro selection ($DEFAULT_DISTRO)
    * [-l]:         lite mode. To help conserve disk space, deletes the building
                    directory once the package is built.
    * [-h]:         help
"
    if [ "`readlink $SHELL`" = "dash" ];then
        echo "
    You are using dash which does not pass args when being sourced.
    To workaround this limitation, use \"set -- args\" prior to
    sourcing this script. For exmaple:
        \$ . $ROOT_DIR/$PROG_NAME
"
    fi
}

# parse the parameters
OLD_OPTIND=$OPTIND
while getopts "m:e:D:lh" setup_flag
do
    case $setup_flag in
        m) MACHINE="$OPTARG";
           ;;
        e) extra_layers="$OPTARG";
           ;;
        D) distro_override="$OPTARG";
           ;;
        l) setup_l='true';
           ;;
        h) setup_h='true';
           ;;
        ?) setup_error='true';
           ;;
    esac
done
OPTIND=$OLD_OPTIND

OE_LAYER_LIST=" \
    meta-openembedded/meta-oe \
    meta-openembedded/meta-filesystems \
    meta-openembedded/meta-initramfs \
    meta-openembedded/meta-networking \
    meta-openembedded/meta-python \
    meta-openembedded/meta-webserver \
    meta-openembedded/meta-perl \
    meta-openembedded/meta-multimedia \
    meta-openembedded/meta-gnome \
    meta-openembedded/meta-xfce \
"

NXP_LAYER_LIST=" \
    meta-freescale \
    meta-alb \
"

EXTRA_LAYER_LIST=" \
    $extra_layers \
"

ALPHA_LAYER_LIST=" \
    meta-alpha \
"

USAGE_LAYER_LIST="$OE_LAYER_LIST \
    $NXP_LAYER_LIST \
    $EXTRA_LAYER_LIST \
    $ALPHA_LAYER_LIST \
"

unset DISTRO
if [ -n "$distro_override" ]; then
    DISTRO="$distro_override";
fi

if [ -z "$DISTRO" ]; then
    DISTRO="$DEFAULT_DISTRO"
fi

# Check the machine type specified
# Note that we intentionally do not test ${MACHINEEXCLUSION}
unset MACHINE_LAYER
if [ -n "${MACHINE}" ]; then
    for layer in $(eval echo $USAGE_LAYER_LIST); do
        if [ -e ${SOURCES_DIR}/${layer}/conf/machine/${MACHINE}.conf ]; then
            MACHINE_LAYER="${SOURCES_DIR}/${layer}"
            break
        fi
    done
else
    usage && clean_up && return $EINVAL
fi

if [ -n "${MACHINE_LAYER}" ]; then 
    echo "Configuring for ${MACHINE} and distro ${DISTRO}..."
else
    echo -e "\nThe \$MACHINE you have specified ($MACHINE) is not supported by this build setup."
    usage && clean_up && return $EINVAL
fi

# 设置默认工作和线程
CPUS=`grep -c processor /proc/cpuinfo`
JOBS="$(( ${CPUS} * 3 / 2))"
THREADS="$(( ${CPUS} * 2 ))"


# 设置项目文件夹位置和名称
PROJECT_DIR=${ROOT_DIR}/build_${MACHINE}
mkdir -p $PROJECT_DIR

DOWNLOADS="$ROOT_DIR/downloads"
mkdir -p $DOWNLOADS
DOWNLOADS=`readlink -f "$DOWNLOADS"`

CACHES="$PROJECT_DIR/sstate-cache"
mkdir -p $CACHES
CACHES=`readlink -f "$CACHES"`

# source oe-init-build-env to init build env
cd $OE_ROOT_DIR
set -- $PROJECT_DIR
. ./oe-init-build-env > /dev/null

#######################################################################################
#
# 对 local.conf 文件进行处理
#
#######################################################################################
# 如果 conf/local.conf 没有生成，直接返回
if [ ! -e conf/local.conf ]; then
    echo "ERROR: the local.conf is not created, Exit ..."
    clean_up && cd $ROOT_DIR && return
fi

# 去掉 local.conf 中的注释行和空行
sed -i -e '/^#.*/d' -e '/^$/d' conf/local.conf

# Change settings according to the environment
sed -e "s,MACHINE ??=.*,MACHINE ??= '$MACHINE',g" \
        -e "s,SDKMACHINE ??=.*,SDKMACHINE ??= '$SDK_MACHINE',g" \
        -e "s,DISTRO ?=.*,DISTRO ?= '$DISTRO',g" \
        -i conf/local.conf

# Clean up PATH, because if it includes tokens to current directories somehow,
# wrong binaries can be used instead of the expected ones during task execution
export PATH="`echo $PATH | sed 's/\(:.\|:\)*:/:/g;s/^.\?://;s/:.\?$//'`"

cat >> conf/local.conf <<-EOF

# Parallelism Options
BB_NUMBER_THREADS = "$THREADS"
PARALLEL_MAKE = "-j $JOBS"
DL_DIR = "$DOWNLOADS"
SSTATE_DIR = "$CACHES"
EOF

for s in $HOME/.oe $HOME/.yocto; do
    if [ -e $s/site.conf ]; then
        echo "Linking $s/site.conf to conf/site.conf"
        ln -s $s/site.conf conf
    fi
done

# option to enable lite mode for now
if test $setup_l; then
    echo "# delete sources after build" >> conf/local.conf
    echo "INHERIT += \"rm_work\"" >> conf/local.conf
    echo >> conf/local.conf
fi

if echo "$MACHINE" |egrep -q "^(b4|p5|t1|t2|t4)"; then
    # disable prelink (for multilib scenario) for now
    sed -i s/image-mklibs.image-prelink/image-mklibs/g conf/local.conf
fi

# make a SOURCE_THIS file
if [ ! -e SOURCE_THIS ]; then
    echo "#!/bin/sh" >> SOURCE_THIS
    echo "cd $OE_ROOT_DIR" >> SOURCE_THIS
    echo "set -- $PROJECT_DIR" >> SOURCE_THIS
    echo ". ./oe-init-build-env > /dev/null" >> SOURCE_THIS
    echo "echo \"Back to build project $PROJECT_DIR.\"" >> SOURCE_THIS
fi

# 添加 layers
for layer in $(eval echo $USAGE_LAYER_LIST); do
    append_layer=""
    if [ -e ${SOURCES_DIR}/${layer} ]; then
        append_layer="${SOURCES_DIR}/${layer}"
    fi
    if [ -n "${append_layer}" ]; then
        append_layer=`readlink -f $append_layer`
        awk '/  "/ && !x {print "'"  ${append_layer}"' \\"; x=1} 1' \
            conf/bblayers.conf > conf/bblayers.conf~
        mv conf/bblayers.conf~ conf/bblayers.conf

        # check if layer is compatible with supported yocto version.
        # if not, make it so.
        conffile_path="${append_layer}/conf/layer.conf"
        yocto_compatible=`grep "LAYERSERIES_COMPAT" "${conffile_path}" | grep "${YOCTO_VERSION}"`
        if [ -z "${yocto_compatible}" ]; then
		    sed -E "/LAYERSERIES_COMPAT/s/(\".*)\"/\1 $YOCTO_VERSION\"/g" -i "${conffile_path}"
		    echo Layer ${layer} updated for ${YOCTO_VERSION}.
		fi
    fi
done

# prompt_message
cd $PROJECT_DIR
clean_up
